package com.ucode.crm.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ucode.crm.dictionary.ContactsShareType;
import com.ucode.crm.dictionary.CrmResultDefineMsg;
import com.ucode.crm.dictionary.ModuleType;
import com.ucode.crm.dictionary.TeamUserPower;
import com.ucode.crm.mapper.ContactsMapper;
import com.ucode.crm.mapper.CustomerMapper;
import com.ucode.crm.mapper.FollowupTeamUserMapper;
import com.ucode.crm.mapper.OwnerChangeRecordMapper;
import com.ucode.crm.mode.Contacts;
import com.ucode.crm.mode.Customer;
import com.ucode.crm.mode.FollowupTeamUser;
import com.ucode.crm.mode.OwnerChangeRecord;
import com.ucode.crm.service.CustomerService;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.ResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.util.IdentifyUtils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;

@Service
public class CustomerServiceImpl implements CustomerService {

    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private ContactsMapper contactsMapper;
    @Autowired
    private FollowupTeamUserMapper followTeamUserMapper;
    @Autowired
    private OwnerChangeRecordMapper ownerChangeRecordMapper;
    
    @Override
    @Transactional(rollbackFor=Exception.class)
    public Customer insert(Customer customer) {
        Date now = new Date();
        Long customerId = IdentifyUtils.getDefaultSnowflakeId();
        customer.setId(customerId);
        customer.setCreatedTime(now);
        customer.setUpdatedTime(now);
        customer.setContactsId(IdentifyUtils.getDefaultSnowflakeId());
        
        Contacts contacts = new Contacts();
        contacts.setId(customer.getContactsId());
        contacts.setDc(0);
        contacts.setName(StrUtil.isNotBlank(customer.getContactsName())?customer.getContactsName():customer.getName());
        contacts.setMobile(customer.getMobile());
        contacts.setTelephone(customer.getTelephone());
        contacts.setSex(customer.getContactsSex());
        contacts.setCreatedTime(now);
        contacts.setUpdatedTime(now);
        contacts.setCustomerId(customerId);
        contacts.setCreateUserId(customer.getCreateUserId());
        contacts.setShareType(ContactsShareType.owner.code);
        contacts.setOwnerUserId(customer.getOwnerUserId());
        
        if(customerMapper.insert(customer) == 0 || 
                contactsMapper.insert(contacts) == 0){
            throw new UcodeServiceException(ResultCodeEnum.FAILED);
        }
       
        if(customer.getOwnerUserId() != null && !customer.getOwnerUserId().equals(0)){
            //客户跟进团队
            FollowupTeamUser customer_followTeamUser = new FollowupTeamUser(customer.getId(), ModuleType.customer.code, customer.getOwnerUserId(), TeamUserPower.owner.code);
            customer_followTeamUser.setId(IdentifyUtils.getDefaultSnowflakeId());
            customer_followTeamUser.setCreatedTime(now);
            customer_followTeamUser.setUpdatedTime(now);
            
            //联系人的跟进人
            FollowupTeamUser contacts_followTeamUser = new FollowupTeamUser(contacts.getId(), ModuleType.contacts.code, customer.getOwnerUserId(), TeamUserPower.owner.code);
            contacts_followTeamUser.setId(IdentifyUtils.getDefaultSnowflakeId());
            contacts_followTeamUser.setCreatedTime(now);
            contacts_followTeamUser.setUpdatedTime(now);
            
            followTeamUserMapper.batchSave(Arrays.asList(customer_followTeamUser,contacts_followTeamUser));
        }
          
        return customer;
    }

    @Override
    public int update(Customer customer) {
        int i = customerMapper.update(customer);
        if(i > 0 && customer.getContactsId() != null && !customer.getContactsId().equals(0)){
            Contacts contacts = new Contacts();
            contacts.setId(customer.getContactsId());
            contacts.setMobile(customer.getMobile());
            contacts.setSex(customer.getContactsSex());
            contactsMapper.update(contacts);
        }
        return i;
    }
    
    @Override
    public int deleteByLogic(Long id) {
        return customerMapper.deleteByLogic(id);
    }
    
    @Override
    public int deletePoolByLogic(Long id) {
        return customerMapper.deletePoolByLogic(id);
    }

    @Override
    public int delete(List<Long> ids) {
        return customerMapper.delete(ids);
    }
    
    @Override
    @Transactional(rollbackFor=Exception.class)
    public int transfer(Long id, Long ownerUserId,Integer optType,Integer power,Long operatorId) {
        
        Customer customer = customerMapper.findById(id);
        if(customer == null || customer.getDeltag() == 1)
            throw new UcodeServiceException(ResultCodeEnum.NO_RECORD);
        
        //公海客户不可转移
        if(customer.getOwnerUserId().equals(0) || customerMapper.transfer(id, ownerUserId) == 0){
            throw new UcodeServiceException(ResultCodeEnum.FAILED.code,CrmResultDefineMsg.customer_pool_transfer_error,customer.getName());
        }
        
        Date now = new Date();
        List<FollowupTeamUser> followupTeamUsers = new ArrayList<FollowupTeamUser>();
        List<OwnerChangeRecord> ownerChangeRecords = new ArrayList<OwnerChangeRecord>();
        
        
        //客户负责人变更记录
        OwnerChangeRecord customer_ownerChangeRecord = new OwnerChangeRecord(customer.getId(), ModuleType.customer.code, customer.getOwnerUserId(), ownerUserId, operatorId);
        customer_ownerChangeRecord.setId(IdentifyUtils.getDefaultSnowflakeId());
        customer_ownerChangeRecord.setCreatedTime(now);
        customer_ownerChangeRecord.setUpdatedTime(now);
        ownerChangeRecords.add(customer_ownerChangeRecord);
        
        //客户跟进团队
        FollowupTeamUser customer_followTeamOwnerUser = new FollowupTeamUser(customer.getId(), ModuleType.customer.code, ownerUserId, TeamUserPower.owner.code);
        customer_followTeamOwnerUser.setId(IdentifyUtils.getDefaultSnowflakeId());
        customer_followTeamOwnerUser.setCreatedTime(now);
        customer_followTeamOwnerUser.setUpdatedTime(now);
        followupTeamUsers.add(customer_followTeamOwnerUser);
        
        FollowupTeamUser customer_oldOwner_FollowTeamOwnerUser = followTeamUserMapper.find(customer.getId(), ModuleType.customer.code, customer.getOwnerUserId());
        //移除原负责人
        if(optType.equals(0) && customer_oldOwner_FollowTeamOwnerUser != null){
            followTeamUserMapper.delete(customer_oldOwner_FollowTeamOwnerUser.getId());
        }
        
        //将原负责人变为团队成员
        if(optType.equals(1) && customer_oldOwner_FollowTeamOwnerUser != null){
            customer_oldOwner_FollowTeamOwnerUser.setPower(power.intValue() == 2 ?TeamUserPower.readWrite.code:TeamUserPower.read.code);
            followupTeamUsers.add(customer_oldOwner_FollowTeamOwnerUser);
        }
        
        /*************************************同步联系人负责人以及联系人跟进团队***************************************/
        //联系人跟进团队
        List<Contacts> contactsList = contactsMapper.findListByCustomerId(customer.getId());
        if(CollUtil.isNotEmpty(contactsList)){
            for(Contacts contacts : contactsList){
                
                //变更联系人负责人
                contactsMapper.updateOwnerUser(contacts.getId(), ownerUserId);
                //联系人负责人变更记录
                OwnerChangeRecord contacts_ownerChangeRecord = new OwnerChangeRecord(contacts.getId(), ModuleType.contacts.code, contacts.getOwnerUserId(), ownerUserId, operatorId);
                contacts_ownerChangeRecord.setId(IdentifyUtils.getDefaultSnowflakeId());
                contacts_ownerChangeRecord.setCreatedTime(now);
                contacts_ownerChangeRecord.setUpdatedTime(now);
                ownerChangeRecords.add(contacts_ownerChangeRecord);
                
                //新增联系人负责人到跟进团队
                FollowupTeamUser contacts_owner_followupTeamUser = new FollowupTeamUser(contacts.getId(), ModuleType.contacts.code, ownerUserId, TeamUserPower.owner.code);
                contacts_owner_followupTeamUser.setId(IdentifyUtils.getDefaultSnowflakeId());
                contacts_owner_followupTeamUser.setCreatedTime(now);
                contacts_owner_followupTeamUser.setUpdatedTime(now);
                followupTeamUsers.add(contacts_owner_followupTeamUser);
                
                //联系人原负责人
                FollowupTeamUser contacts_followupTeamUser = followTeamUserMapper.find(contacts.getId(), ModuleType.contacts.code, customer.getOwnerUserId());
                if(contacts_followupTeamUser == null)
                    continue;
                
                if(ContactsShareType.team.code == contacts.getShareType()){
                    contacts_followupTeamUser.setPower(2==power? TeamUserPower.readWrite.code : TeamUserPower.read.code);
                    followupTeamUsers.add(contacts_followupTeamUser);
                }else{
                    followTeamUserMapper.delete(contacts_followupTeamUser.getId());
                }
                
            }
        }
        
        if(ownerChangeRecords.size() > 0)
            ownerChangeRecordMapper.batchInsert(ownerChangeRecords);
        
        if(followupTeamUsers.size() > 0)
            followTeamUserMapper.batchSave(followupTeamUsers);
        
        return 1;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public int putInPool(Long id, Long operatorId) {
        
        Customer customer = customerMapper.findById(id);
        if(customer == null || customer.getDeltag() == 1)
            throw new UcodeServiceException(ResultCodeEnum.NO_RECORD);
        
        //已经在公海
        if(customer.getOwnerUserId().equals(0) || customerMapper.putInPool(operatorId) ==0){
            throw new UcodeServiceException(ResultCodeEnum.FAILED.code,CrmResultDefineMsg.customer_existed_pool_error,customer.getName());
        }
        
        List<OwnerChangeRecord> ownerChangeRecords = new ArrayList<OwnerChangeRecord>();
        Date now = new Date();
        
        //客户负责人变更记录
        OwnerChangeRecord customer_ownerChangeRecord = new OwnerChangeRecord(customer.getId(), ModuleType.customer.code, customer.getOwnerUserId(), 0L, operatorId);
        customer_ownerChangeRecord.setId(IdentifyUtils.getDefaultSnowflakeId());
        customer_ownerChangeRecord.setCreatedTime(now);
        customer_ownerChangeRecord.setUpdatedTime(now);
        ownerChangeRecords.add(customer_ownerChangeRecord);
        //移除客户跟进团队
        List<FollowupTeamUser> customer_followTeamOwnerUsers = followTeamUserMapper.findList(customer.getId(), ModuleType.customer.code);
        if(CollUtil.isNotEmpty(customer_followTeamOwnerUsers)){
            List<Long> ids = customer_followTeamOwnerUsers.stream().map(m -> m.getId()).distinct().collect(Collectors.toList());
            followTeamUserMapper.batchDelete(ids);
        }
        
        /*************************************同步移除联系人跟进团队***************************************/
        //联系人跟进团队
        List<Contacts> contactsList = contactsMapper.findListByCustomerId(customer.getId());
        if(CollUtil.isNotEmpty(contactsList)){
            for(Contacts contacts : contactsList){
                if(contacts.getOwnerUserId() != null && !contacts.getOwnerUserId().equals(0)){
                    contactsMapper.updateOwnerUser(contacts.getId(), 0L);
                    //联系人负责人变更记录
                    OwnerChangeRecord contacts_ownerChangeRecord = new OwnerChangeRecord(contacts.getId(), ModuleType.contacts.code, contacts.getOwnerUserId(), 0L, operatorId);
                    contacts_ownerChangeRecord.setId(IdentifyUtils.getDefaultSnowflakeId());
                    contacts_ownerChangeRecord.setCreatedTime(now);
                    contacts_ownerChangeRecord.setUpdatedTime(now);
                    ownerChangeRecords.add(contacts_ownerChangeRecord);
                }
                
                List<FollowupTeamUser> contacts_followTeamOwnerUsers = followTeamUserMapper.findList(contacts.getId(), ModuleType.contacts.code);
                if(CollUtil.isNotEmpty(contacts_followTeamOwnerUsers)){
                    List<Long> ids =contacts_followTeamOwnerUsers.stream().map(m -> m.getId()).distinct().collect(Collectors.toList());
                    followTeamUserMapper.batchDelete(ids);
                }
            }
        }
        
        if(ownerChangeRecords.size() > 0)
            ownerChangeRecordMapper.batchInsert(ownerChangeRecords);
        
        return 1;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public int receive(Long id, Long ownerUserId, Long operatorId) {
        Customer customer = customerMapper.findById(id);
        if(customer == null || customer.getDeltag() == 1)
            throw new UcodeServiceException(ResultCodeEnum.NO_RECORD);
        
        //不是公海客户不可分配
        if(!customer.getOwnerUserId().equals(0) || customerMapper.receive(id, ownerUserId) == 0){
            throw new UcodeServiceException(ResultCodeEnum.FAILED.code,CrmResultDefineMsg.customer_pool_receive_error,customer.getName());
        }
        
        List<FollowupTeamUser> followupTeamUsers = new ArrayList<FollowupTeamUser>();
        List<OwnerChangeRecord> ownerChangeRecords = new ArrayList<OwnerChangeRecord>();
        Date now = new Date();
        
        //客户负责人变更记录
        OwnerChangeRecord customer_ownerChangeRecord = new OwnerChangeRecord(customer.getId(), ModuleType.customer.code, customer.getOwnerUserId(), ownerUserId, operatorId);
        customer_ownerChangeRecord.setId(IdentifyUtils.getDefaultSnowflakeId());
        customer_ownerChangeRecord.setCreatedTime(now);
        customer_ownerChangeRecord.setUpdatedTime(now);
        ownerChangeRecords.add(customer_ownerChangeRecord);
        
        //客户跟进团队
        FollowupTeamUser customer_followTeamOwnerUser = new FollowupTeamUser(customer.getId(), ModuleType.customer.code, ownerUserId, TeamUserPower.owner.code);
        customer_followTeamOwnerUser.setId(IdentifyUtils.getDefaultSnowflakeId());
        customer_followTeamOwnerUser.setCreatedTime(now);
        customer_followTeamOwnerUser.setUpdatedTime(now);
        followupTeamUsers.add(customer_followTeamOwnerUser);
        
        /*****************************同步更新联系人跟进团队*********************************/
        //联系人跟进团队
        List<Contacts> contactsList = contactsMapper.findListByCustomerId(customer.getId());
        if(CollUtil.isNotEmpty(contactsList)){
            for(Contacts contacts : contactsList){
                
                contactsMapper.updateOwnerUser(contacts.getId(), ownerUserId);
                //联系人负责人变更记录
                OwnerChangeRecord contacts_ownerChangeRecord = new OwnerChangeRecord(contacts.getId(), ModuleType.contacts.code, contacts.getOwnerUserId(), ownerUserId, operatorId);
                contacts_ownerChangeRecord.setId(IdentifyUtils.getDefaultSnowflakeId());
                contacts_ownerChangeRecord.setCreatedTime(now);
                contacts_ownerChangeRecord.setUpdatedTime(now);
                ownerChangeRecords.add(contacts_ownerChangeRecord);
                
                FollowupTeamUser contacts_owner_followupTeamUser = new FollowupTeamUser(contacts.getId(), ModuleType.contacts.code, ownerUserId, TeamUserPower.owner.code);
                contacts_owner_followupTeamUser.setId(IdentifyUtils.getDefaultSnowflakeId());
                contacts_owner_followupTeamUser.setCreatedTime(now);
                contacts_owner_followupTeamUser.setUpdatedTime(now);
                followupTeamUsers.add(contacts_owner_followupTeamUser);
            }
        }
        return 1;
    }
    
    @Override
    public Customer findById(Long id) {
        return customerMapper.findById(id);
    }

    @Override
    public List<Customer> findByIds(List<Long> ids) {
        return customerMapper.findByIds(ids);
    }

    @Override
    public Paginator<Customer> queryPoolPage(String name, String mobile, Integer areaId, Integer level, Integer source, Date startTime, Date endTime,
            int pagesize, int page) {
        
        return null;
    }
    
}
